#include "lista.h"


int criaLista(ppLista pp) {
  if ((*pp = (pLista) calloc(1,sizeof(Lista))) != NULL)
    return 1;
  return 0;
}


int inserePrimeiro(pLista p, void *novo, int tamanho) {
  pNoDados temp;

  if ((temp = (pNoDados) calloc(1,sizeof(NoDados))) != NULL) {
    temp->dados = (void *) malloc(tamanho);
    memcpy(temp->dados, novo, tamanho);
    temp->prox = p->inicio;
    p->inicio = temp;
    return 1;
  }
  return 0;
}


int insereUltimo(pLista p, void *novo, int tamanho) {
  pNoDados aux,temp;

  if ((temp = (pNoDados) calloc(1,sizeof(NoDados))) != NULL) {
    temp->dados = (void *) malloc(tamanho);
    memcpy(temp->dados, novo, tamanho);
    aux = p->inicio;
    if (p->inicio != NULL) {
      while(aux->prox != NULL)
        aux = aux->prox;
      aux->prox = temp;
    }
    else
      p->inicio = temp; 
    return 1;
  }
  return 0;
}

int inserePoslog(pLista p, int poslog, void *novo, int tamanho) {
  pNoDados pre,pos;
  int cont;

  if (p->inicio != NULL && poslog > 1) {
    pos = pre = p->inicio;
    cont = 1;
    while(cont < poslog && pos->prox != NULL) {
      pre = pos;
      pos = pos->prox;
      cont++;
    }
    if (cont == poslog) {
      if ((pre->prox = (pNoDados) calloc(1,sizeof(NoDados))) != NULL) {
        pre->prox->dados = (void *) malloc(tamanho);
        memcpy(pre->prox->dados, novo, tamanho);
      }
      pre->prox->prox = pos;
      return 1;
    }
  }
  return 0;
}


int retiraPrimeiro(pLista p) {
  pNoDados aux;

  if (p->inicio != NULL){
    aux = p->inicio;
    p->inicio = aux->prox;
    free(aux->dados);
    free(aux);
    return 1;
  }
  return 0;
}


int retiraUltimo(pLista p) {
  pNoDados pre, pos;

  if (p->inicio != NULL) {
    pre = pos = p->inicio;
	while(pos->prox != NULL) {
      pre = pos;
      pos = pos->prox;
    }
    free(pos->dados);
    free(pos);
    pre = NULL;
    return 1;
  }
  return 0;
}


int retiraPoslog(pLista p, int poslog) {
  int cont;
  pNoDados pre, pos;

  if(p->inicio != NULL) {
    pos = pre = p->inicio;
    cont = 1;
    while (cont < poslog && pos->prox != NULL) {
      pre = pos;
      pos = pos->prox;
      cont++;
    }
    if (cont == poslog) {
      pre->prox = pos->prox;
      free(pos->dados);
      free(pos);
      return 1;
    }
  }
  return 0;
}


int buscaPrimeiro(pLista p, void *pReg, int tamanho) {
  if (p->inicio != NULL) {
    memcpy(pReg, p->inicio->dados, tamanho);
    return 1;
  }
  return 0;
}

int buscaUltimo(pLista p, void *pReg, int tamanho) {
  pNoDados aux;

  aux = p->inicio;
  if (aux != NULL) {
    while(aux->prox != NULL)
      aux = aux->prox;
    memcpy(pReg, aux->dados, tamanho);
    return 1;
  }
  return 0;
}


int buscaPoslog(pLista p, int poslog, void *pReg, int tamanho) {
  pNoDados aux;
  int cont;

  if (p->inicio != NULL) {
    aux = p->inicio;
    for (cont = 1; cont < poslog && aux->prox != NULL; cont++)
      aux = aux->prox;
    if (cont == poslog) {
      memcpy(pReg, aux->dados, tamanho);
      return 1;
    }		
  }
  return 0;
}


void purgaLista(pLista p) {
  pNoDados aux;

  while (p->inicio != NULL) {
    aux = p->inicio;
    p->inicio = aux->prox;
    free(aux->dados);
    free(aux);
  }
}


void destroiLista(ppLista pp) {
  pNoDados aux;

  while ((*pp)->inicio != NULL) {
    aux = (*pp)->inicio;
    (*pp)->inicio = aux->prox;
    free(aux->dados);
    free(aux);
  }
  free(*pp);
  (*pp) = NULL;
}


int testaVazia(pLista p) {
  if(p->inicio != NULL)
	return 0;
  return 1;
}


int tamanhoLista(pLista p) {
  int cont = 0;
  pNoDados aux;

  aux = p->inicio;
  while (aux != NULL) {
    aux = aux->prox;
    cont++;
  }
  return cont;
}
